// This file is part of OpenMeca, an easy software to do mechanical simulation.
//
// Author(s)    :  - Damien ANDRE  <openmeca@gmail.com>
//
// Copyright (C) 2012 Damien ANDRE
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.


#include "OpenMeca/GlobalSetting/MenuManager.hpp"
#include "OpenMeca/Core/GlobalSettingCommonProperty.hpp"

namespace OpenMeca
{
  namespace GlobalSetting
  {

    void
    MenuManager::Init()
    {
      Core::Singleton< Core::GlobalSettingCommonProperty<MenuManager> >::Get();
      Core::Singleton<MenuManager>::Get().ReadXmlFile();
    }

    const std::string
    MenuManager::GetStrType()
    {
      return "MenuManager";
    }

    

    MenuManager::MenuManager()
      :Core::GlobalSettingInterface<MenuManager>(),
       menuKey_("Menu"),
       classKey_("Class"),
       actionKey_("Action"),
       separatorKey_("Separator")
    {
      
    }
    
   
    MenuManager::~MenuManager()
    {
    }

    std::string 
    MenuManager::GetClassId() const
    {
      return GetStrType();
    }

    void MenuManager::ReadXmlFile()
    {
       std::cout << "Building menus...";

      QDomDocument doc("mydocument");
      QFile& file = OpenXmlConfigFile();
      assert(doc.setContent(&file));
      QDomNode n = doc.firstChild();
      std::map<const QDomElement*, QMenu* > menuNode;

      while (!n.isNull()) 
	{
	  if (n.isElement()) 
	    {
	      QDomElement e = n.toElement();
	      if (e.tagName()==QString(GetClassId().c_str()))
		{
		  QDomNode n1 = e.firstChild ();
		  while (!n1.isNull()) 
		    {
		      if (n1.isElement()) 
			{
			  QDomElement e1 = n1.toElement();
			  const QString Title = e1.attribute("Title");
			  assert(Title!=QString());
			  QMenu* menu = Gui::MainWindow::Get().menuBar()->addMenu(Title);
			  AddAction(e1, menu);
			}
		      n1 = n1.nextSibling();
		    }
		}
	    }
	  n = n.nextSibling();
	}
      std::cout << "ok" << std::endl;
    }
    
    void
    MenuManager::AddAction(QDomElement& e, QMenu* menu)
    {
      assert(e.tagName()==QString(menuKey_.c_str()));
      QDomNode n = e.firstChild ();
      while (!n.isNull()) 
	{
	  if (n.isElement()) 
	    {
	      QDomElement e = n.toElement();
	      if (e.tagName()==QString(classKey_.c_str()))
		{
		  const QString type = e.attribute("Type");
		  Core::CommonProperty& theClass = Core::CommonProperty::GetClass(type.toStdString());

		  QDomNode n1 = e.firstChild ();
		  while (!n1.isNull()) 
		    {
		      if (n1.isElement()) 
			{
			  
			  QDomElement e1 = n1.toElement();
			  if (e1.tagName()==QString(actionKey_.c_str()))
			    {
			      QString Id = e1.attribute("Id");
			      menu->addAction(&theClass.GetAction(Id.toStdString()));
			    }
			  else if (e1.tagName()==QString(separatorKey_.c_str()))
			    {
			      menu->addSeparator();
			    }
			    
			}
		      n1 = n1.nextSibling();
		    }
		    
		  
		}
	      
	      else if (e.tagName()==QString(menuKey_.c_str()))
		{
		  const QString Title = e.attribute("Title");
		  assert(Title!=QString());
		  QMenu* childMenu = menu->addMenu(Title);
		  AddAction(e, childMenu);
		}
	      
	      else if (e.tagName()==QString(separatorKey_.c_str()))
		{
		  menu->addSeparator();
		}

	      
	    }
	  n = n.nextSibling();
	}
    }


    void MenuManager::WriteXmlFile()
    {
      assert(0);//TODO
      
    }

  }
}
